package org.tool.reflect;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 泛型相关工具类
 *
 * @author 李坤
 * @date 2022/7/10 17:04
 */
public abstract class GenericUtil {

    /**
     * 获得指定对象的父类对应的泛型参数的实际类型。如 ClassA extends ClassB<String>
     *
     * @param target 给定的对象，该类必须继承范型父类
     *
     * @return 范型参数的实际类型，如果没有实现ParameterizedType接口，即不支持泛型，所以直接返回<code>Object.class</code>
     */
    public static Class getSuperClassGenericType(Object target) {
        return GenericUtil.getSuperClassGenericType(target.getClass(), 0);
    }

    /**
     * 获得指定类的父类对应的泛型参数的实际类型。如 ClassA extends ClassB<String>
     *
     * @param clazz 给定的类型，该类必须继承范型父类
     * @param index 泛型参数所在索引，从0开始
     *
     * @return 范型参数的实际类型，如果没有实现ParameterizedType接口，即不支持泛型，所以直接返回<code>Object.class</code>
     */
    public static Class getSuperClassGenericType(final Class<?> clazz, final int index) {
        Type superclass = clazz.getGenericSuperclass();

        if (superclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) superclass;
            return (Class) parameterizedType.getActualTypeArguments()[index];
        }
        return Object.class;
    }

}
